home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / HALOS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-27  |  30.8 KB  |  1,368 lines

  1. /****************************************************************************
  2. *                   halo.c
  3. *
  4. *  This module contains all functions for halo effects.
  5. *
  6. *  This file was written by Zsolt Szalavari. He wrote the code for
  7. *  halos and generously provided us these enhancements.
  8. *
  9. *  from Persistence of Vision(tm) Ray Tracer
  10. *  Copyright 1996 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. *  NOTICE: This source code file is provided so that users may experiment
  13. *  with enhancements to POV-Ray and to port the software to platforms other
  14. *  than those supported by the POV-Ray Team.  There are strict rules under
  15. *  which you are permitted to use this file.  The rules are in the file
  16. *  named POVLEGAL.DOC which should be distributed with this file. If
  17. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  19. *  Forum.  The latest version of POV-Ray may be found there as well.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26.  
  27. /*
  28.   ===========================================================================
  29.   Copyright 1995 Zsolt Szalavari.
  30.   Vienna University of Technology - Institute of Computer Graphics
  31.   All Rights Reserved.
  32.   ===========================================================================
  33.    NAME:       halos.c
  34.    TYPE:       c code
  35.    PROJECT:    Halo Visualisation Project
  36.    CONTENT:
  37.    VERSION:    1.0.0
  38.   ===========================================================================
  39.     AUTHOR:     zss     Zsolt Szalavari
  40.   ===========================================================================
  41.    HISTORY:
  42.  
  43.    29-May-95           zss     last modification
  44.    10-Mar-95           zss     created
  45.   ===========================================================================
  46. */
  47.  
  48. #include "frame.h"
  49. #include "povproto.h"
  50. #include "vector.h"
  51. #include "povray.h"
  52. #include "atmosph.h"
  53. #include "pattern.h"
  54. #include "texture.h"
  55. #include "halos.h"
  56. #include "objects.h"
  57. #include "matrices.h"
  58. #include "lighting.h"
  59. #include "colour.h"
  60.  
  61.  
  62. /*****************************************************************************
  63. * Local preprocessor defines
  64. ******************************************************************************/
  65.  
  66. #define SMALLSTEP 0.1
  67.  
  68.  
  69.  
  70. /*****************************************************************************
  71. * Local typedefs
  72. ******************************************************************************/
  73.  
  74.  
  75.  
  76. /*****************************************************************************
  77. * Local variables
  78. ******************************************************************************/
  79.  
  80.  
  81.  
  82. /*****************************************************************************
  83. * Static functions
  84. ******************************************************************************/
  85.  
  86. static DBL determine_density PARAMS((HALO *Halo, VECTOR Place));
  87. static void compute_halo_colour PARAMS((COLOUR Colour, HALO *Halo, DBL value));
  88. static void sample_halos PARAMS((RAY *Ray, HALO *Halo, VECTOR In_Point, DBL dist, VECTOR One_Step, COLOUR Halo_Colour, int Light_Ray_Flag));
  89. static void supersample_halos PARAMS((RAY *Ray, int level, HALO *Halo,
  90.   DBL d1, COLOUR C1, DBL d3, COLOUR C3, VECTOR In_Point, VECTOR One_Step,
  91.   int Light_Ray_FLag));
  92.  
  93.  
  94.  
  95. /*****************************************************************************
  96. *
  97. * FUNCTION
  98. *
  99. *   Do_Halo
  100. *
  101. * INPUT
  102. *
  103. * OUTPUT
  104. *
  105. * RETURNS
  106. *
  107. * AUTHOR
  108. *
  109. *   Zsolt Szalavari
  110. *
  111. * DESCRIPTION
  112. *
  113. *   This one does it !!!
  114. *
  115. *   It is the main calculation routine, which is called whenever a
  116. *   transparent object was hit and it was a halo by fortune. Roughly said
  117. *   it gets the info of the entry and the exit point of the ray in a halo,
  118. *   and more info about what object was hit. Performing the calculations
  119. *   it passes a colour value back which represents the appearance of the
  120. *   halo combined with everything behind. Detailed explanation inline.
  121. *
  122. * CHANGES
  123. *
  124. *  May 1995 : Creation.
  125. *
  126. *  Aug 1995 : Modified sampling loop. Added jitter. [DB]
  127. *
  128. ******************************************************************************/
  129.  
  130. void Do_Halo(Halo, Ray, Ray_Intersection, Colour, Light_Ray_Flag)
  131. HALO *Halo;
  132. RAY *Ray;
  133. INTERSECTION *Ray_Intersection;
  134. COLOUR Colour;
  135. int Light_Ray_Flag;
  136. {
  137.   int i;
  138.   DBL dist, dist_prev, jdist;
  139.   DBL Distance, Stepsize;
  140.   DBL Halo_Factor, Halo_Factor_Inverse;
  141.   DBL Total_Density, Temp_Density;
  142.   VECTOR In_Point, Out_Point, P1, P2, D;
  143.   VECTOR One_Step;
  144.   COLOUR Halo_Colour, Halo_Colour_prev, Temp_Colour;
  145.  
  146.   /*
  147.    * Get start and end point.
  148.    *
  149.    * YOU SHOULD ALWAYS USE UNIT SIZE GENERATED OBJECTS, WHICH ARE
  150.    * SCALED, ROTATED AND TRANSLATED TO THEIR FINAL POSITION AND SHAPE!!!
  151.    * THUS YOU WILL BE SAVE FROM ANY HOLY CRASHES!!!
  152.    */
  153.  
  154.   Assign_Vector(In_Point,  Ray->Initial);
  155.   Assign_Vector(Out_Point, Ray_Intersection->IPoint);
  156.  
  157.   Distance = Ray_Intersection->Depth;
  158.  
  159.   /*
  160.    * Get step size based on number of samples.
  161.    */
  162.  
  163.   Stepsize = Distance / Halo->Samples;
  164.  
  165.   /*
  166.    * Get step vector, i.e. the vetor pointing in the direction of the
  167.    * current ray and having a length that is equal to one sample step.
  168.    */
  169.  
  170.   VScale(One_Step, Ray->Direction, Stepsize);
  171.  
  172.   /*
  173.    * Resize Stepsize to remove dependencies due to container object
  174.    * size. This assumes that the halo is designed for a unit size
  175.    * object (that's normally the case because the halo density map
  176.    * works on unit size objects).
  177.    */
  178.  
  179.   MInvTransPoint(P1, In_Point,  Halo->Container_Trans);
  180.   MInvTransPoint(P2, Out_Point, Halo->Container_Trans);
  181.  
  182.   VSub(D, P2, P1);
  183.  
  184.   VLength(dist, D);
  185.  
  186.   /* 
  187.    * We can resize the Stepsize because it's only used for weighting 
  188.    * the halo samples, not for stepping through the halo.
  189.    */
  190.  
  191.   Stepsize = dist / Halo->Samples;
  192.  
  193.   /*
  194.    * Here it happens. The main stepping loop to step through the halo space.
  195.    */
  196.  
  197.   Make_Colour(Temp_Colour, 0.0, 0.0, 0.0);
  198.  
  199.   Make_Colour(Halo_Colour_prev, 0.0, 0.0, 0.0);
  200.  
  201.   dist_prev = 0.0;
  202.  
  203.   Total_Density = 0.0;
  204.  
  205.   for (i = 0; i <= Halo->Samples; i++)
  206.   {
  207.     /* Get distance to next sample point. */
  208.  
  209.     dist = (DBL)i + 0.5;
  210.  
  211.     /* Sample at current location if last sample hasn't been traced yet. */
  212.  
  213.     if (i < Halo->Samples)
  214.     {
  215.       /* Get jittered distance. */
  216.  
  217.       jdist = dist + (FRAND() - 0.5) * Halo->Jitter;
  218.  
  219.       sample_halos(Ray, Halo, In_Point, jdist, One_Step, Halo_Colour, Light_Ray_Flag);
  220.     }
  221.  
  222.     if (i)
  223.     {
  224.       /* If the last sample has been traced we just want to add it. */
  225.  
  226.       if (i < Halo->Samples)
  227.       {
  228.         /* Do the current and previous colours differ too much? */
  229.  
  230.         if ((Halo->AA_Level > 0) && (Colour_Distance(Halo_Colour, Halo_Colour_prev) >= Halo->AA_Threshold))
  231.         {
  232.           /* Supersample between current and previous point. */
  233.  
  234.           supersample_halos(Ray, 1, Halo, dist_prev, Halo_Colour_prev, dist, Halo_Colour, In_Point, One_Step, Light_Ray_Flag);
  235.  
  236.           Halo_Colour[RED]    = Halo_Colour_prev[RED]    = 0.5 * (Halo_Colour[RED]    + Halo_Colour_prev[RED]);
  237.           Halo_Colour[GREEN]  = Halo_Colour_prev[GREEN]  = 0.5 * (Halo_Colour[GREEN]  + Halo_Colour_prev[GREEN]);
  238.           Halo_Colour[BLUE]   = Halo_Colour_prev[BLUE]   = 0.5 * (Halo_Colour[BLUE]   + Halo_Colour_prev[BLUE]);
  239.           Halo_Colour[FILTER] = Halo_Colour_prev[FILTER] = 0.5 * (Halo_Colour[FILTER] + Halo_Colour_prev[FILTER]);
  240.           Halo_Colour[TRANSM] = Halo_Colour_prev[TRANSM] = 0.5 * (Halo_Colour[TRANSM] + Halo_Colour_prev[TRANSM]);
  241.         }
  242.       }
  243.  
  244.       Total_Density = min(1.0, Total_Density + Stepsize * Halo_Colour_prev[TRANSM]);
  245.  
  246.       /*
  247.        * After we stored the total density we sum up the colour values.
  248.        * For GLOWING each color contribution is attenuated by the total
  249.        * density up to this point (i.e. light emerging from a point in a
  250.        * GLOW is attenuated by the particles lying in front of it).
  251.        */
  252.  
  253.       switch (Halo->Rendering_Type)
  254.       {
  255.         case HALO_DUST:
  256.         case HALO_EMITTING:
  257.  
  258.           Temp_Colour[RED]    += Halo_Colour_prev[RED]    * Halo_Colour_prev[TRANSM];
  259.           Temp_Colour[GREEN]  += Halo_Colour_prev[GREEN]  * Halo_Colour_prev[TRANSM];
  260.           Temp_Colour[BLUE]   += Halo_Colour_prev[BLUE]   * Halo_Colour_prev[TRANSM];
  261.           Temp_Colour[FILTER] += Halo_Colour_prev[FILTER] * Halo_Colour_prev[TRANSM];
  262.           Temp_Colour[TRANSM] += Halo_Colour_prev[TRANSM] * Halo_Colour_prev[TRANSM];
  263.  
  264.           break;
  265.  
  266.         case HALO_GLOWING:
  267.  
  268.           Temp_Density = 1.0 - Total_Density;
  269.  
  270.           Temp_Colour[RED]    += Temp_Density * Halo_Colour_prev[RED]    * Halo_Colour_prev[TRANSM];
  271.           Temp_Colour[GREEN]  += Temp_Density * Halo_Colour_prev[GREEN]  * Halo_Colour_prev[TRANSM];
  272.           Temp_Colour[BLUE]   += Temp_Density * Halo_Colour_prev[BLUE]   * Halo_Colour_prev[TRANSM];
  273.           Temp_Colour[FILTER] += Temp_Density * Halo_Colour_prev[FILTER] * Halo_Colour_prev[TRANSM];
  274.           Temp_Colour[TRANSM] += Temp_Density * Halo_Colour_prev[TRANSM] * Halo_Colour_prev[TRANSM];
  275.  
  276.           break;
  277.       }
  278.     }
  279.  
  280.     Assign_Colour(Halo_Colour_prev, Halo_Colour);
  281.  
  282.     dist_prev = dist;
  283.   }
  284.  
  285.   /*
  286.    * Scale all the values by the stepsize for sampling rate independency.
  287.    */
  288.  
  289.   Temp_Colour[RED]    *= Stepsize;
  290.   Temp_Colour[GREEN]  *= Stepsize;
  291.   Temp_Colour[BLUE]   *= Stepsize;
  292.   Temp_Colour[FILTER] *= Stepsize;
  293.   Temp_Colour[TRANSM] *= Stepsize;
  294.  
  295.   /*
  296.    * Use the different rendering methods to determine the final colour.
  297.    */
  298.  
  299.   Halo_Factor = 1.0 - Total_Density;
  300.  
  301.   if (!Light_Ray_Flag)
  302.   {
  303.     switch (Halo->Rendering_Type)
  304.     {
  305.       case HALO_ATTENUATING:
  306.  
  307.         compute_halo_colour(Halo_Colour, Halo, Total_Density);
  308.  
  309.         Halo_Factor_Inverse = 1.0 - Halo_Factor;
  310.  
  311.         Colour[RED]    = Colour[RED]    * Halo_Factor + Halo_Colour[RED]    * Halo_Factor_Inverse;
  312.         Colour[GREEN]  = Colour[GREEN]  * Halo_Factor + Halo_Colour[GREEN]  * Halo_Factor_Inverse;
  313.         Colour[BLUE]   = Colour[BLUE]   * Halo_Factor + Halo_Colour[BLUE]   * Halo_Factor_Inverse;
  314.         Colour[FILTER] = Colour[FILTER] * Halo_Factor + Halo_Colour[FILTER] * Halo_Factor_Inverse;
  315.         Colour[TRANSM] = Colour[TRANSM] * Halo_Factor + Halo_Colour[TRANSM] * Halo_Factor_Inverse;
  316.  
  317.         break;
  318.  
  319.       case HALO_EMITTING:
  320.       case HALO_DUST:
  321.       case HALO_GLOWING:
  322.  
  323.         Colour[RED]    = Colour[RED]    * Halo_Factor + Temp_Colour[RED];
  324.         Colour[GREEN]  = Colour[GREEN]  * Halo_Factor + Temp_Colour[GREEN];
  325.         Colour[BLUE]   = Colour[BLUE]   * Halo_Factor + Temp_Colour[BLUE];
  326.         Colour[FILTER] = Colour[FILTER] * Halo_Factor + Temp_Colour[FILTER];
  327.         Colour[TRANSM] = Colour[TRANSM] * Halo_Factor + Temp_Colour[TRANSM];
  328.  
  329.         break;
  330.     }
  331.   }
  332.  
  333.   Increase_Counter(stats[Halo_Rays_Traced]);
  334. }
  335.  
  336.  
  337.  
  338. /*****************************************************************************
  339. *
  340. * FUNCTION
  341. *
  342. *   sample_halos
  343. *
  344. * INPUT
  345. *
  346. * OUTPUT
  347. *
  348. * RETURNS
  349. *
  350. * AUTHOR
  351. *
  352. *   Zsolt Szalavari
  353. *
  354. * DESCRIPTION
  355. *
  356. * CHANGES
  357. *
  358. *   Aug 1995 : Moved here from Do_Halo. [DB]
  359. *
  360. ******************************************************************************/
  361.  
  362. static void sample_halos(Ray, Halo, In_Point, dist, One_Step, Halo_Colour, Light_Ray_Flag)
  363. RAY *Ray;
  364. HALO *Halo;
  365. VECTOR In_Point, One_Step;
  366. DBL dist;
  367. COLOUR Halo_Colour;
  368. int Light_Ray_Flag;
  369. {
  370.   DBL Density, Light_Source_Depth, Cos_Ray_Light, Phase, g, f, fi;
  371.   VECTOR Place, Local_Place;
  372.   COLOUR Temp_Colour, Temp2_Colour;
  373.   COLOUR Light_Colour;
  374.   RAY Light_Source_Ray;
  375.   LIGHT_SOURCE *Light_Source;
  376.   HALO *Local_Halo;
  377.  
  378.   /* Get sample point in world coordinates. */
  379.  
  380.   VEvaluateRay(Place, In_Point, dist, One_Step);
  381.  
  382.   /* Look for multiple halos and get their density & colour contribution. */
  383.  
  384.   Make_Colour(Halo_Colour, 0.0, 0.0, 0.0);
  385.  
  386.   for (Local_Halo = Halo; Local_Halo != NULL; Local_Halo = Local_Halo->Next_Halo)
  387.   {
  388.     Make_Colour(Temp_Colour, 0.0, 0.0, 0.0);
  389.  
  390.     MInvTransPoint(Local_Place, Place, Local_Halo->Trans);
  391.  
  392.     Density = determine_density(Local_Halo, Local_Place);
  393.  
  394.     compute_halo_colour(Temp_Colour, Local_Halo, Density);
  395.  
  396.     /*
  397.      * If the halo happens to be DUST, we have to look for lights.
  398.      * The routine looks for all light sources, checks whether they are
  399.      * blocked or attenuated (spot lights). Finally it calculates the
  400.      * phase depending on the cosine of the angle between eye-ray and
  401.      * light-ray.
  402.      *
  403.      * If the current ray is a light source ray, i.e. it is not a viewing
  404.      * ray, do not determine attenuation for dust.
  405.      */
  406.  
  407.     if ((!Light_Ray_Flag) && (Local_Halo->Rendering_Type == HALO_DUST))
  408.     {
  409.       /* Do not change the filter and transmittance channels. */
  410.  
  411. /*
  412.       Temp_Colour[RED] = Temp_Colour[GREEN] = Temp_Colour[BLUE] = 0.0;
  413. */
  414.       Make_Colour(Temp2_Colour, 0.0, 0.0, 0.0);
  415.  
  416.       for (Light_Source = Frame.Light_Sources; Light_Source != NULL; Light_Source = Light_Source->Next_Light_Source)
  417.       {
  418.         if (!Test_Shadow(Light_Source, &Light_Source_Depth, &Light_Source_Ray, Ray, Place, Light_Colour))
  419.         {
  420.           VDot(Cos_Ray_Light, Ray->Direction, Light_Source_Ray.Direction);
  421.  
  422.           switch (Halo->Dust_Type)
  423.           {
  424.             case MIE_HAZY_SCATTERING:
  425.  
  426.               Phase = 0.1 * (1.0 + 0.03515625 * pow((1.0 + Cos_Ray_Light), 8.0));
  427.  
  428.               break;
  429.  
  430.             case MIE_MURKY_SCATTERING:
  431.  
  432.               Phase = 0.019607843 * (1.0 + 1.1641532e-8 * pow(1.0 + Cos_Ray_Light, 32.0));
  433.  
  434.               break;
  435.  
  436.             case RAYLEIGH_SCATTERING:
  437.  
  438.               Phase = (1.0 + Sqr(Cos_Ray_Light)) / 2.0;
  439.  
  440.               break;
  441.  
  442.             case HENYEY_GREENSTEIN_SCATTERING:
  443.  
  444.               g = Local_Halo->Eccentricity;
  445.  
  446.               Phase = (1.0 - Sqr(g)) / pow((1.0 + Sqr(g) - 2.0*g*Cos_Ray_Light), 1.5);
  447.  
  448.               break;
  449.  
  450.             case ISOTROPIC_SCATTERING:
  451.             default:
  452.  
  453.               Phase = 1.0;
  454.           }
  455.  
  456.           Temp2_Colour[RED]   += Light_Colour[RED]   * Phase;
  457.           Temp2_Colour[GREEN] += Light_Colour[GREEN] * Phase;
  458.           Temp2_Colour[BLUE]  += Light_Colour[BLUE]  * Phase;
  459.         }
  460.       }
  461.  
  462.       f = Temp_Colour[FILTER];
  463.  
  464.       fi = 1.0 - f;
  465.  
  466.       Temp_Colour[RED]   = Temp2_Colour[RED]   * (fi + f * Temp_Colour[RED]);
  467.       Temp_Colour[GREEN] = Temp2_Colour[GREEN] * (fi + f * Temp_Colour[GREEN]);
  468.       Temp_Colour[BLUE]  = Temp2_Colour[BLUE]  * (fi + f * Temp_Colour[BLUE]);
  469.     }
  470.  
  471.     /* The contribution of multiple halos is added up here. */
  472.  
  473.     Halo_Colour[RED]    += Temp_Colour[RED]    - Halo_Colour[RED]    * Temp_Colour[RED];
  474.     Halo_Colour[GREEN]  += Temp_Colour[GREEN]  - Halo_Colour[GREEN]  * Temp_Colour[GREEN];
  475.     Halo_Colour[BLUE]   += Temp_Colour[BLUE]   - Halo_Colour[BLUE]   * Temp_Colour[BLUE];
  476.     Halo_Colour[FILTER] += Temp_Colour[FILTER] - Halo_Colour[FILTER] * Temp_Colour[FILTER];
  477.     Halo_Colour[TRANSM] += Temp_Colour[TRANSM] - Halo_Colour[TRANSM] * Temp_Colour[TRANSM];
  478.   }
  479. }
  480.  
  481.  
  482.  
  483. /*****************************************************************************
  484. *
  485. * FUNCTION
  486. *
  487. *   supersample_halos
  488. *
  489. * INPUT
  490. *
  491. *   level - level of recursion
  492. *   Halo  - pointer to first halo
  493. *   d1    - distance to lower sample
  494. *   d3    - distance to upper sample
  495. *
  496. * OUTPUT
  497. *
  498. *   C1    - Color of lower sample
  499. *   C3    - Color of upper sample
  500. *
  501. * RETURNS
  502. *
  503. * AUTHOR
  504. *
  505. *   Dieter Bayer
  506. *
  507. * DESCRIPTION
  508. *
  509. *   Recursevily supersample between two points on the ray.
  510. *
  511. * CHANGES
  512. *
  513. *   Aug 1995 : Creation.
  514. *
  515. ******************************************************************************/
  516.  
  517. static void supersample_halos(Ray, level, Halo, d1, C1, d3, C3, In_Point, One_Step, Light_Ray_Flag)
  518. RAY *Ray;
  519. int level, Light_Ray_Flag;
  520. HALO *Halo;
  521. DBL d1, d3;
  522. COLOUR C1, C3;
  523. VECTOR In_Point, One_Step;
  524. {
  525.   DBL d2, jdist;
  526.   COLOUR C2;
  527.  
  528.   Increase_Counter(stats[Halo_Supersamples]);
  529.  
  530.   /* Sample between lower and upper point. */
  531.  
  532.   d2 = 0.5 * (d1 + d3);
  533.  
  534.   jdist = d2 + Halo->Jitter * 0.5 * (d3 - d1) * (FRAND() - 0.5);
  535.  
  536.   sample_halos(Ray, Halo, In_Point, jdist, One_Step, C2, Light_Ray_Flag);
  537.  
  538.   /* Test for further supersampling. */
  539.  
  540.   if (level < Halo->AA_Level)
  541.   {
  542.     if (Colour_Distance(C1, C2) >= Halo->AA_Threshold)
  543.     {
  544.       /* Supersample between lower and middle point. */
  545.  
  546.       supersample_halos(Ray, level+1, Halo, d1, C1, d2, C2, In_Point, One_Step, Light_Ray_Flag);
  547.     }
  548.  
  549.     if (Colour_Distance(C2, C3) >= Halo->AA_Threshold)
  550.     {
  551.       /* Supersample between current and higher point. */
  552.  
  553.       supersample_halos(Ray, level+1, Halo, d2, C2, d3, C3, In_Point, One_Step, Light_Ray_Flag);
  554.     }
  555.   }
  556.  
  557.   /* Add supersampled colors. */
  558.  
  559.   VLinComb2(C1, 0.75, C1, 0.25, C2);
  560.   VLinComb2(C3, 0.25, C2, 0.75, C3);
  561. }
  562.  
  563.  
  564.  
  565. /*****************************************************************************
  566. *
  567. * FUNCTION
  568. *
  569. *   compute_halo_colour
  570. *
  571. * INPUT
  572. *
  573. *   Halo   - Current halo
  574. *   value  - Current value of the scalar field
  575. *
  576. * OUTPUT
  577. *
  578. *   Colour - Color of halo for given density
  579. *
  580. * RETURNS
  581. *
  582. * AUTHOR
  583. *
  584. *   Zsolt Szalavari
  585. *
  586. * DESCRIPTION
  587. *
  588. *   This one will calculate the Halo_Colour, depending on the estimated
  589. *   density. It's actually a mirror of the Compute_Colour routine in
  590. *   texture.c, modified to work with halos. It interpolates the colour
  591. *   from the colour_map.
  592. *
  593. * CHANGES
  594. *
  595. *   May 1995 : Creation.
  596. *
  597. ******************************************************************************/
  598.  
  599. static void compute_halo_colour (Colour, Halo, value)
  600. COLOUR Colour;
  601. HALO *Halo;
  602. DBL value;
  603. {
  604.   DBL fraction;
  605.   COLOUR C1, C2;
  606.   BLEND_MAP *Blend_Map = Halo->Blend_Map;
  607.   BLEND_MAP_ENTRY *Curr, *Prev;
  608.  
  609.   value = fmod(value * Halo->Frequency + Halo->Phase, 1.00001);
  610.  
  611.   /* allow negative Frequency */
  612.  
  613.   if (value < 0.0)
  614.   {
  615.     value -= floor(value);
  616.   }
  617.  
  618.   Search_Blend_Map(value, Blend_Map, &Prev, &Curr);
  619.  
  620.   if (Prev != Curr)
  621.   {
  622.     fraction = (value - Prev->value) / (Curr->value - Prev->value);
  623.  
  624.     Assign_Colour(C1, Curr->Vals.Colour);
  625.     Assign_Colour(C2, Prev->Vals.Colour);
  626.  
  627.     Colour[RED]    = C2[RED]    + fraction * (C1[RED]    - C2[RED]);
  628.     Colour[GREEN]  = C2[GREEN]  + fraction * (C1[GREEN]  - C2[GREEN]);
  629.     Colour[BLUE]   = C2[BLUE]   + fraction * (C1[BLUE]   - C2[BLUE]);
  630.     Colour[FILTER] = C2[FILTER] + fraction * (C1[FILTER] - C2[FILTER]);
  631.     Colour[TRANSM] = C2[TRANSM] + fraction * (C1[TRANSM] - C2[TRANSM]);
  632.   }
  633.   else
  634.   {
  635.     Assign_Colour(Colour, Curr->Vals.Colour);
  636.   }
  637. }
  638.  
  639.  
  640.  
  641. /*****************************************************************************
  642. *
  643. * FUNCTION
  644. *
  645. *   determine_density
  646. *
  647. * INPUT
  648. *
  649. *   Halo  - Current halo
  650. *   Place - Current location of evaluation (in halo space)
  651. *
  652. * OUTPUT
  653. *
  654. * RETURNS
  655. *
  656. *   DBL - Density in current location
  657. *
  658. * AUTHOR
  659. *
  660. *   Zsolt Szalavari
  661. *
  662. * DESCRIPTION
  663. *
  664. *   This routine is dedicated to estimate the density, OOPS, the change in
  665. *   the density at a given point in halo space. First it adds turbulence
  666. *   (if there is some to add) to the vector pointing at a place in halo
  667. *   space. Then it determines a 'radius', depending on the spatial mapping
  668. *   of the density vals. After that we get the density as a constant, linear
  669. *   or whatever function of this radius. At the end we cut the value to a
  670. *   tiny unit intervall.
  671. *
  672. * CHANGES
  673. *
  674. *   May 1995 : Creation.
  675. *
  676. ******************************************************************************/
  677.  
  678. static DBL determine_density(Halo, Place)
  679. HALO *Halo;
  680. VECTOR Place;
  681. {
  682.   DBL Radius, Solution;
  683.   VECTOR Local_Place, Temp;
  684.  
  685.   /* Add turbulence. */
  686.  
  687.   if (Halo->Turb != NULL)
  688.   {
  689.     DTurbulence(Temp, Place, Halo->Turb);
  690.  
  691.     Local_Place[X] = Place[X] + Temp[X] * Halo->Turb->Turbulence[X];
  692.     Local_Place[Y] = Place[Y] + Temp[Y] * Halo->Turb->Turbulence[Y];
  693.     Local_Place[Z] = Place[Z] + Temp[Z] * Halo->Turb->Turbulence[Z];
  694.   }
  695.   else
  696.   {
  697.     Assign_Vector(Local_Place, Place);
  698.   }
  699.  
  700.   /* Estimate radius, depending on mapping type. */
  701.  
  702.   switch (Halo->Mapping_Type)
  703.   {
  704.     case HALO_CYLINDRICAL_MAP:
  705.  
  706.       Radius = sqrt(Sqr(Local_Place[X]) + Sqr(Local_Place[Z]));
  707.  
  708.       break;
  709.  
  710.     case HALO_PLANAR_MAP:
  711.  
  712.       Radius = fabs(Local_Place[Y]);
  713.  
  714.       break;
  715.  
  716.     case HALO_BOX_MAP:
  717.  
  718.       Radius = max(fabs(Local_Place[X]), max(fabs(Local_Place[Y]), fabs(Local_Place[Z])));
  719.  
  720.       break;
  721.  
  722.     case HALO_SPHERICAL_MAP:
  723.     default:
  724.  
  725.       VLength(Radius, Local_Place);
  726.  
  727.       break;
  728.   }
  729.  
  730.   /* Clip density. */
  731.  
  732.   if (Radius < 0.0)
  733.   {
  734.     Radius = 0.0;
  735.   }
  736.   else
  737.   {
  738.     if (Radius > 1.0)
  739.     {
  740.       Radius = 1.0;
  741.     }
  742.   }
  743.  
  744.   /* Calculate density by choosen formula. */
  745.  
  746.   switch (Halo->Type)
  747.   {
  748.     case HALO_LINEAR:
  749.  
  750.       Solution = Halo->Max_Value * (1.0 - Radius);
  751.  
  752.       break;
  753.  
  754.     case HALO_CUBIC:
  755.  
  756.       Solution = Halo->Max_Value * ((2.0 * Radius - 3.0 ) * Sqr(Radius) + 1.0);
  757.  
  758.       break;
  759.  
  760.     case HALO_POLY:
  761.  
  762.       Solution = Halo->Max_Value * pow((1.0 - Radius), Halo->Exponent);
  763.  
  764.       break;
  765.  
  766.     case HALO_CONSTANT:
  767.     default:
  768.  
  769.       Solution = Halo->Max_Value;
  770.  
  771.       break;
  772.   }
  773.  
  774.   Increase_Counter(stats[Halo_Samples]);
  775.  
  776.   return(Solution);
  777. }
  778.  
  779.  
  780.  
  781. /*****************************************************************************
  782. *
  783. * FUNCTION
  784. *
  785. *   Create_Halo
  786. *
  787. * INPUT
  788. *
  789. * OUTPUT
  790. *
  791. * RETURNS
  792. *
  793. * AUTHOR
  794. *
  795. *   Zsolt Szalavari
  796. *
  797. * DESCRIPTION
  798. *
  799. *   In the beginning there was a simple halo, beeing a default for everything!
  800. *
  801. * CHANGES
  802. *
  803. *   May 1995 : Creation.
  804. *
  805. ******************************************************************************/
  806.  
  807. HALO *Create_Halo ()
  808. {
  809.   HALO *New;
  810.  
  811.   New = (HALO *)POV_MALLOC(sizeof(HALO), "halo");
  812.  
  813.   Init_TPat_Fields((TPATTERN *)New);
  814.  
  815.   New->Type  = HALO_NO_HALO;
  816.   New->Flags = 0;
  817.  
  818.   New->Rendering_Type = HALO_EMITTING;
  819.   New->Mapping_Type   = HALO_SPHERICAL_MAP;
  820.   New->Dust_Type      = ISOTROPIC_SCATTERING;
  821.  
  822.   New->Max_Value      = 1.0;
  823.   New->Exponent       = 1.0;
  824.   New->Eccentricity   = 0.0;
  825.   New->Samples        = 10;
  826.   New->Jitter         = 0.0;
  827.   New->Frequency      = 1.0;
  828.   New->Phase          = 0.0;
  829.   New->Blend_Map      = NULL;
  830.   New->Next_Halo      = NULL;
  831.   New->Turb           = NULL;
  832.  
  833.   New->AA_Level     = 0;
  834.   New->AA_Threshold = 0.3;
  835.  
  836.   New->Trans = Create_Transform();
  837.  
  838.   New->Container_Trans = Create_Transform();
  839.  
  840.   return(New);
  841. }
  842.  
  843.  
  844.  
  845. /*****************************************************************************
  846. *
  847. * FUNCTION
  848. *
  849. *   Copy_Halo
  850. *
  851. * INPUT
  852. *
  853. * OUTPUT
  854. *
  855. * RETURNS
  856. *
  857. * AUTHOR
  858. *
  859. *   Zsolt Szalavari
  860. *
  861. * DESCRIPTION
  862. *
  863. *   Designing multiply halos requires copying the old data fields to the new
  864. *   halo. Exactly that's the reason why this routine has been written.
  865. *
  866. * CHANGES
  867. *
  868. *   May 1995 : Creation.
  869. *
  870. ******************************************************************************/
  871.  
  872. HALO *Copy_Halo (Old)
  873. HALO *Old;
  874. {
  875.   HALO *New, *First, *Previous, *Local_Halo;
  876.  
  877.   Previous = First = NULL;
  878.  
  879.   if (Old != NULL)
  880.   {
  881.     for (Local_Halo = Old; Local_Halo != NULL; Local_Halo = Local_Halo->Next_Halo)
  882.     {
  883.       New = Create_Halo();
  884.  
  885.       Destroy_Transform(New->Trans);
  886.       Destroy_Transform(New->Container_Trans);
  887.  
  888.       *New = *Local_Halo;
  889.  
  890.       New->Trans = Copy_Transform (Local_Halo->Trans);
  891.       New->Container_Trans = Copy_Transform (Local_Halo->Container_Trans);
  892.  
  893.       New->Blend_Map = Copy_Blend_Map (Local_Halo->Blend_Map);
  894.  
  895.       New->Turb = (TURB *)Copy_Warps((WARP *)(Local_Halo->Turb));
  896.  
  897.       if (First == NULL)
  898.       {
  899.         First = New;
  900.       }
  901.  
  902.       if (Previous != NULL)
  903.       {
  904.         Previous->Next_Halo = New;
  905.       }
  906.  
  907.       Previous = New;
  908.     }
  909.   }
  910.   else
  911.   {
  912.     First = NULL;
  913.   }
  914.  
  915.   return(First);
  916. }
  917.  
  918.  
  919.  
  920. /*****************************************************************************
  921. *
  922. * FUNCTION
  923. *
  924. *   Destroy_Halo
  925. *
  926. * INPUT
  927. *
  928. * OUTPUT
  929. *
  930. * RETURNS
  931. *
  932. * AUTHOR
  933. *
  934. *   Zsolt Szalavari
  935. *
  936. * DESCRIPTION
  937. *
  938. *   To the ashes with the remainals of a data structure. It's hard.
  939. *
  940. * CHANGES
  941. *
  942. *   May 1995 : Creation.
  943. *
  944. ******************************************************************************/
  945.  
  946. void Destroy_Halo (Halo)
  947. HALO *Halo;
  948. {
  949.   HALO *Local_Halo, *Temp;
  950.  
  951.   if (Halo == NULL)
  952.   {
  953.     return;
  954.   }
  955.  
  956.   Local_Halo = Halo;
  957.  
  958.   while (Local_Halo != NULL)
  959.   {
  960.     Destroy_Blend_Map(Local_Halo->Blend_Map);
  961.     Destroy_Transform(Local_Halo->Trans);
  962.     Destroy_Transform(Local_Halo->Container_Trans);
  963.     Destroy_Warps((WARP *)(Local_Halo->Turb));
  964.  
  965.     Temp = Local_Halo->Next_Halo;
  966.  
  967.     POV_FREE(Local_Halo);
  968.  
  969.     Local_Halo = Temp;
  970.   }
  971. }
  972.  
  973.  
  974.  
  975. /*****************************************************************************
  976. *
  977. * FUNCTION
  978. *
  979. *   Translate_One_Halo
  980. *
  981. * INPUT
  982. *
  983. * OUTPUT
  984. *
  985. * RETURNS
  986. *
  987. * AUTHOR
  988. *
  989. *   Zsolt Szalavari
  990. *
  991. * DESCRIPTION
  992. *
  993. *   Compute the translation transform and transform the halo.
  994. *
  995. * CHANGES
  996. *
  997. *   May 1995 : Creation.
  998. *
  999. ******************************************************************************/
  1000.  
  1001. void Translate_One_Halo(Halo, Trans)
  1002. HALO *Halo;
  1003. TRANSFORM *Trans;
  1004. {
  1005.   if (Halo != NULL)
  1006.   {
  1007.     Transform_One_Halo(Halo, Trans);
  1008.   }
  1009. }
  1010.  
  1011.  
  1012.  
  1013. /*****************************************************************************
  1014. *
  1015. * FUNCTION
  1016. *
  1017. *   Rotate_One_Halo
  1018. *
  1019. * INPUT
  1020. *
  1021. * OUTPUT
  1022. *
  1023. * RETURNS
  1024. *
  1025. * AUTHOR
  1026. *
  1027. *   Zsolt Szalavari
  1028. *
  1029. * DESCRIPTION
  1030. *
  1031. *   Compute the rotation transform and transform the halo.
  1032. *
  1033. * CHANGES
  1034. *
  1035. *   May 1995 : Creation.
  1036. *
  1037. ******************************************************************************/
  1038.  
  1039. void Rotate_One_Halo(Halo, Trans)
  1040. HALO *Halo;
  1041. TRANSFORM *Trans;
  1042. {
  1043.   if (Halo != NULL)
  1044.   {
  1045.     Transform_One_Halo(Halo, Trans);
  1046.   }
  1047. }
  1048.  
  1049.  
  1050.  
  1051. /*****************************************************************************
  1052. *
  1053. * FUNCTION
  1054. *
  1055. *   Scale_One_Halo
  1056. *
  1057. * INPUT
  1058. *
  1059. * OUTPUT
  1060. *
  1061. * RETURNS
  1062. *
  1063. * AUTHOR
  1064. *
  1065. *   Zsolt Szalavari
  1066. *
  1067. * DESCRIPTION
  1068. *
  1069. *   Compute the scaling transform and transform the halo.
  1070. *
  1071. * CHANGES
  1072. *
  1073. *   May 1995 : Creation.
  1074. *
  1075. ******************************************************************************/
  1076.  
  1077. void Scale_One_Halo(Halo, Trans)
  1078. HALO *Halo;
  1079. TRANSFORM *Trans;
  1080. {
  1081.   if (Halo != NULL)
  1082.   {
  1083.     Transform_One_Halo(Halo, Trans);
  1084.   }
  1085. }
  1086.  
  1087.  
  1088.  
  1089. /*****************************************************************************
  1090. *
  1091. * FUNCTION
  1092. *
  1093. *   Transform_One_Halo
  1094. *
  1095. * INPUT
  1096. *
  1097. * OUTPUT
  1098. *
  1099. * RETURNS
  1100. *
  1101. * AUTHOR
  1102. *
  1103. *   Zsolt Szalavari
  1104. *
  1105. * DESCRIPTION
  1106. *
  1107. *   Transform one halo.
  1108. *
  1109. * CHANGES
  1110. *
  1111. *   May 1995 : Creation.
  1112. *
  1113. ******************************************************************************/
  1114.  
  1115. void Transform_One_Halo(Halo,Trans)
  1116. HALO *Halo;
  1117. TRANSFORM *Trans;
  1118. {
  1119.   if (Halo != NULL)
  1120.   {
  1121.     Compose_Transforms(Halo->Trans, Trans);
  1122.   }
  1123. }
  1124.  
  1125.  
  1126. /*****************************************************************************
  1127. *
  1128. * FUNCTION
  1129. *
  1130. *   Transform_Halo
  1131. *
  1132. * INPUT
  1133. *
  1134. * OUTPUT
  1135. *
  1136. * RETURNS
  1137. *
  1138. * AUTHOR
  1139. *
  1140. *   Zsolt Szalavari
  1141. *
  1142. * DESCRIPTION
  1143. *
  1144. *   Transform halo and apply the trafo to all of it's multiply friends.
  1145. *
  1146. * CHANGES
  1147. *
  1148. *   May 1995 : Creation.
  1149. *
  1150. ******************************************************************************/
  1151.  
  1152. void Transform_Halo(Halo,Trans)
  1153. HALO *Halo;
  1154. TRANSFORM *Trans;
  1155. {
  1156.   HALO *Local_Halo;
  1157.  
  1158.   if (Halo != NULL)
  1159.   {
  1160.     for (Local_Halo = Halo; Local_Halo != NULL; Local_Halo = Local_Halo->Next_Halo)
  1161.     {
  1162.       Compose_Transforms(Local_Halo->Trans, Trans);
  1163.     }
  1164.   }
  1165. }
  1166.  
  1167.  
  1168. /*****************************************************************************
  1169. *
  1170. * FUNCTION
  1171. *
  1172. *   Post_Halo
  1173. *
  1174. * INPUT
  1175. *
  1176. * OUTPUT
  1177. *
  1178. * RETURNS
  1179. *
  1180. * AUTHOR
  1181. *
  1182. *   Zsolt Szalavari
  1183. *
  1184. * DESCRIPTION
  1185. *
  1186. *   To get everything correctly caught by the routines looking for a
  1187. *   halo, some parameters must be set previously. Care is taken of
  1188. *   eventually bad links.
  1189. *
  1190. * CHANGES
  1191. *
  1192. *   May 1995 : Creation.
  1193. *
  1194. ******************************************************************************/
  1195.  
  1196. void Post_Halo(Texture)
  1197. TEXTURE *Texture;
  1198. {
  1199.   if (Texture->Halo == NULL)
  1200.   {
  1201.     return;
  1202.   }
  1203.  
  1204.   if (Texture->Halo->Flags & POST_DONE)
  1205.   {
  1206.     return;
  1207.   }
  1208.  
  1209.   Texture->Halo->Flags |= POST_DONE;
  1210. }
  1211.  
  1212.  
  1213.  
  1214. /*****************************************************************************
  1215. *
  1216. * FUNCTION
  1217. *
  1218. *   Rotate_Halo_Container
  1219. *
  1220. * INPUT
  1221. *
  1222. * OUTPUT
  1223. *
  1224. * RETURNS
  1225. *
  1226. * AUTHOR
  1227. *
  1228. *   Dieter Bayer
  1229. *
  1230. * DESCRIPTION
  1231. *
  1232. *   Transform halo container.
  1233. *
  1234. * CHANGES
  1235. *
  1236. *   Mar 1996 : Creation.
  1237. *
  1238. ******************************************************************************/
  1239.  
  1240. void Rotate_Halo_Container(Textures, Trans)
  1241. TEXTURE *Textures;
  1242. TRANSFORM *Trans;
  1243. {
  1244.   Transform_Halo_Container(Textures, Trans);
  1245. }
  1246.  
  1247.  
  1248.  
  1249. /*****************************************************************************
  1250. *
  1251. * FUNCTION
  1252. *
  1253. *   Scale_Halo_Container
  1254. *
  1255. * INPUT
  1256. *
  1257. * OUTPUT
  1258. *
  1259. * RETURNS
  1260. *
  1261. * AUTHOR
  1262. *
  1263. *   Dieter Bayer
  1264. *
  1265. * DESCRIPTION
  1266. *
  1267. *   Transform halo container.
  1268. *
  1269. * CHANGES
  1270. *
  1271. *   Mar 1996 : Creation.
  1272. *
  1273. ******************************************************************************/
  1274.  
  1275. void Scale_Halo_Container(Textures, Trans)
  1276. TEXTURE *Textures;
  1277. TRANSFORM *Trans;
  1278. {
  1279.   Transform_Halo_Container(Textures, Trans);
  1280. }
  1281.  
  1282.  
  1283.  
  1284. /*****************************************************************************
  1285. *
  1286. * FUNCTION
  1287. *
  1288. *   Translate_Halo_Container
  1289. *
  1290. * INPUT
  1291. *
  1292. * OUTPUT
  1293. *
  1294. * RETURNS
  1295. *
  1296. * AUTHOR
  1297. *
  1298. *   Dieter Bayer
  1299. *
  1300. * DESCRIPTION
  1301. *
  1302. *   Transform halo container.
  1303. *
  1304. * CHANGES
  1305. *
  1306. *   Mar 1996 : Creation.
  1307. *
  1308. ******************************************************************************/
  1309.  
  1310. void Translate_Halo_Container(Textures, Trans)
  1311. TEXTURE *Textures;
  1312. TRANSFORM *Trans;
  1313. {
  1314.   Transform_Halo_Container(Textures, Trans);
  1315. }
  1316.  
  1317.  
  1318.  
  1319. /*****************************************************************************
  1320. *
  1321. * FUNCTION
  1322. *
  1323. *   Transform_Halo_Container
  1324. *
  1325. * INPUT
  1326. *
  1327. * OUTPUT
  1328. *
  1329. * RETURNS
  1330. *
  1331. * AUTHOR
  1332. *
  1333. *   Dieter Bayer
  1334. *
  1335. * DESCRIPTION
  1336. *
  1337. *   Transform halo container.
  1338. *
  1339. * CHANGES
  1340. *
  1341. *   Mar 1996 : Creation.
  1342. *
  1343. ******************************************************************************/
  1344.  
  1345. void Transform_Halo_Container(Textures, Trans)
  1346. TEXTURE *Textures;
  1347. TRANSFORM *Trans;
  1348. {
  1349.   HALO *Local_Halo;
  1350.   TEXTURE *Layer;
  1351.  
  1352.   for (Layer = Textures; Layer != NULL; Layer = (TEXTURE *)Layer->Next)
  1353.   {
  1354.     if (Layer->Type == PLAIN_PATTERN)
  1355.     {
  1356.       if (Layer->Halo != NULL)
  1357.       {
  1358.         for (Local_Halo = Layer->Halo; Local_Halo != NULL; Local_Halo = Local_Halo->Next_Halo)
  1359.         {
  1360.           Compose_Transforms(Local_Halo->Container_Trans, Trans);
  1361.         }
  1362.       }
  1363.     }
  1364.   }
  1365. }
  1366.  
  1367.  
  1368.